
#include <BEvent>
#include <BPainter>
#include <BImage>
#include <BFont>
#include <BStyle>
#include <BStyle>
#include <BSizePolicy>

#include <BLabel>
#include "member_BLabel.h"

using namespace BWE;

#define member					(*(member_BLabel*)_ptr)
#define member_allocate()		_ptr = new member_BLabel(this)
#define member_release()		delete (member_BLabel*)_ptr

BLabel::BLabel(BWidget* parent) : BWidget(parent)
{
	member_allocate();
	this->setBorder(0);
}
BLabel::BLabel(const BString& text, BWidget* parent) : BWidget(parent)
{
	member_allocate();
	this->setBorder(0);
	setText(text);
}
BLabel::BLabel(BImage* image, BWidget* parent) : BWidget(parent)
{
	member_allocate();
	this->setBorder(0);
	setImage(image);
}
BLabel::BLabel(BImage* image, const BString& text, BWidget* parent) : BWidget(parent)
{
	member_allocate();
	this->setBorder(0);
	setImage(image);
	setText(text);
}
BLabel::~BLabel()
{
	member_release();
}

void BLabel::setForm(Form form)
{
	if (member.ia_form != form)
	{
		member.ia_form = form;
		member.dirty = true;
		this->fresh();
	}
}
Form BLabel::form() const
{
	return member.ia_form;
}

void BLabel::setAlign(Align align)
{
	if (member.ia_align != align)
	{
		member.ia_align = align;
		member.dirty = true;
		this->fresh();
		emit(Signal_AlignChanged, align);
	}
}
Align BLabel::align() const
{
	return member.ia_align;
}

void BLabel::setText(const BString& text)
{
	if(member.text != text)
	{
		member.text = text;
		member.dirty = true;
		Policy widthPolicy = this->widthPolicy();
		Policy heightPolicy = this->heightPolicy();
		if (widthPolicy & Policy_Preferred || heightPolicy & Policy_Preferred)
		{
			this->adjust();
		}
		emit(Signal_TextChanged, member.text);
		this->fresh();
	}
}
const BString& BLabel::text() const
{
	return member.text;
}

void BLabel::setImage(BImage* image)
{
	if(member.image != image)
	{
		member.image = image;
		member.dirty = true;
		Policy widthPolicy = this->widthPolicy();
		Policy heightPolicy = this->heightPolicy();
		if (widthPolicy & Policy_Preferred || heightPolicy & Policy_Preferred)
		{
			this->adjust();
		}
		emit(Signal_ImageChanged, member.image.ptr());
		this->fresh();
	}
}
BImage* BLabel::image()
{
	return member.image.ptr();
}
const BImage* BLabel::image() const
{
	return member.image.ptr();
}

void BLabel::setImageSize(const BSize& imageSize)
{
	if (member.imageSize != imageSize)
	{
		member.imageSize = imageSize;
		member.dirty = true;
		this->fresh();
	}
}
const BSize& BLabel::imageSize() const
{
	return member.imageSize;
}

BSize BLabel::sizeHint() const
{
	if (member.dirty)
	{
		member.freshRects();
		member.dirty = false;
	}
	BSize hsize = BWidget::preferSize(member.ia_hintSize);
	return hsize;
}

void BLabel::resizeEvent(const BEvent& event)
{
	member.dirty = true;
}

void BLabel::styleEvent(const BEvent& event)
{
	const BStyle* style = this->realStyle();

	const BValue& textValue = style->value(Value_Text);
	if (textValue.valid())
		member.text = (BString&)textValue;

	const BValue& alignValue = style->value(Value_Align);
	if (alignValue.valid())
		member.ia_align = alignValue;

	const BValue& imageValue = style->value(Value_Image);
	if (imageValue.valid())
		member.image = (BImage*)imageValue;

	const BValue& imageSizeValue = style->value(Value_Image_Size);
	if (imageSizeValue.valid())
		member.imageSize = imageSizeValue;

	member.dirty = true;
}
void BLabel::freshEvent(const BEvent& event)
{
	if (member.dirty)
	{
		member.freshRects();
		member.dirty = false;
	}
}
void BLabel::paintEvent(const BEvent& event)
{
	BPainter painter(this);
	painter.drawBackground();
	painter.drawPerch();

	if (member.image)
	{
		painter.drawImage(member.ia_imageRect, member.image);
	}
	if (this->enabled())
		painter.setColor(Color_Text);
	else
		painter.setColor(Color_Text_Disable);
	if (member.t_text.size())
		painter.drawText(member.ia_textRect, member.t_text, member.ia_align);
	else
		painter.drawText(member.ia_textRect, member.text, member.ia_align);
	painter.drawMargin();
	painter.drawBorder();
}
